package com.tianruan.dc.common.exception;

import com.tianruan.dc.common.constant.GlobalExceptionEnum;
import com.tianruan.dc.common.utils.response.VResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.common.exceptions.BadClientCredentialsException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

/**
 * @PS 全局异常接收类
 */
@RestControllerAdvice
@Slf4j
@Order(-100)
public class GlobalExceptionHandler {


    @ExceptionHandler(GlobalException.class)
    public VResponse<Object> handleWarnException(HttpServletRequest request, GlobalException exception) {
        log.error("错误code: {}；错误信息: {}", exception.getCode(), exception.getMsg());
        return VResponse.error(exception.getCode(), exception.getMsg()).setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
//        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ExceptionVO(exception.getCode(),exception.getMsg()) );
    }


    @ExceptionHandler(Exception.class)
    public VResponse<Object> Exception(HttpServletRequest request, Exception exception) {
        return VResponse.error(1000, exception.getMessage());
    }

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(org.springframework.security.access.AccessDeniedException.class)
    public VResponse<Object> accessDeniedException(HttpServletRequest request, Exception e) {

        return VResponse.error(1000, e.getMessage());
    }

    @ExceptionHandler(RuntimeException.class)
    public VResponse<Object> runtimeException(HttpServletRequest request, Exception e) {

        return VResponse.error(1000, e.getMessage());
    }


    // 无效允许异常
    @ExceptionHandler(BadClientCredentialsException.class)
    public VResponse<Object> illegalAccessException(HttpServletRequest request, InvalidGrantException exception) {
        return VResponse.error(1000, exception.getMessage());
    }

    // 无效允许异常
    @ExceptionHandler(InvalidGrantException.class)
    public VResponse<Object> invalidGrantException(HttpServletRequest request, InvalidGrantException exception) {
        if (exception instanceof InvalidGrantException) {
            if (exception.getMessage().contains("坏的凭证")) {
                return VResponse.result(GlobalExceptionEnum.ERROP_USER_PASSWORD);
            }
        }
        // 登录失败或者刷新token无效
        return VResponse.error(1000, "用户名密码错误或用户名不存在！");
    }

    // 没有该grantType异常
    @ExceptionHandler(UnsupportedGrantTypeException.class)
    public VResponse<Object> UnsupportedGrantTypeException(HttpServletRequest request, UnsupportedGrantTypeException exception) {
        return VResponse.error(1000, exception.getMessage());
    }

    /**
     * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public VResponse<Object> ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));
        return VResponse.error(GlobalExceptionEnum.CONSTRAINT_VIOLATION_ERROR.getCode(), message);
    }

}
